package engine.videoCapture;

import java.awt.Dimension;
import java.io.IOException;
import java.util.Vector;

import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Format;
import javax.media.Manager;
import javax.media.NoDataSourceException;
import javax.media.control.FormatControl;
import javax.media.format.VideoFormat;
import javax.media.protocol.CaptureDevice;
import javax.media.protocol.CaptureDevice;
import javax.media.protocol.DataSource;

import engine.exceptions.NoWebcamFoundException;

/**
 * configureWebcam
 * @author Manu
 * Finds and configures a webcam.
 */
public class ConfigureWebcam{
	
	/* *********************************************************
	 * Attributes
	 * ********************************************************* */
	
	private static CaptureDeviceInfo _WebcamInformation;
	private static DataSource _DataSource;
	static FormatControl [] _FormatControls;
	static Format [] _Formats;
	static VideoFormat _VideoFormat = null;
	
	/* *********************************************************
	 * Instance Methods
	 * ********************************************************* */
	
	/**
	 * This method finds and configures a webcam.
	 * @return DataSource the DataSource from the webcam
	 * @throws NoWebcamFoundException
	 */
	@SuppressWarnings("unchecked")
	public static 	DataSource doConfigureWebcam() throws NoWebcamFoundException{
		System.out.println("eg.videoCapture.ConfigureWebCam doConfig start !");
		_VideoFormat = new VideoFormat(VideoFormat.YUV, new Dimension(320, 240), 153600, VideoFormat.byteArray, 15);
		// generate the list of the webcam available in YUV mode
		Vector _webcamList = CaptureDeviceManager.getDeviceList(
				_VideoFormat);
		if (!_webcamList.isEmpty()) {
			System.out.println("Webcam(s) found in YUV mode!\n");
		}else {
			System.out.println("No webcam found in YUV mode.\n");
			throw new NoWebcamFoundException();
		}
		//get the info about the first element in the list
		_WebcamInformation = (CaptureDeviceInfo) _webcamList.firstElement();
		
		//create a DataSource from the webcam
		try {
			_DataSource = 
				Manager.createDataSource(_WebcamInformation.getLocator());
		} 
		catch (NoDataSourceException e) {}
		catch (IOException e) {}
		System.out.println("DataSource created.\n");
		
		//get the format we want to use from the supported format list
		_FormatControls = ((CaptureDevice) _DataSource).getFormatControls();
		for (int i = 0; i < _FormatControls.length; i++) {
			if (_FormatControls[i] == null)
				continue;
			_Formats = _FormatControls[i].getSupportedFormats();
			if (matches(_VideoFormat, _Formats) != null) {
				_FormatControls[i].setFormat(_VideoFormat);
			}
		}
		
		return _DataSource;
	}
	
	/**
	 * Finds a format in a supported format list
	 * @param format The format we are looking for
	 * @param supported The list of supported formats
	 * @return The Format we were looking for if found, null otherwise
	 */
	private static Format matches(Format format, Format [] supported) {
		if (supported == null)
			return null;
		for (int i = 0; i < supported.length; i++) {
			if (supported[i].matches(format))
				return supported[i];
		}
		return null;
	}
}
